package cn.itsub.sodo;

import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import cn.itsub.sodo.action.base.Action;
import cn.itsub.sodo.action.ActionManager;
import cn.itsub.sodo.core.types.Size;
import cn.itsub.sodo.core.types.Vec2;

public class Node {
	
	
	protected boolean paused=false;
	public Vec2 position=new Vec2();	//位置
	protected Size size;				//尺寸
	protected float rotation;				//旋转角度
	protected float scaleX=1;			//缩放倍数
	protected float scaleY=1;			//缩放倍数
	
	protected float opacity=1;			//透明度0-1（1不透明）
	protected float anchorX = 0.5f;
	protected float anchorY = 0.5f;

	public boolean flipX = false;	//X轴镜像翻转
	public boolean flipY = false;	//Y轴镜像翻转

	protected boolean visible=true;
	
	protected int oldRotation;			//旧的旋转角度 
	protected double oldScaleX;			//旧的X轴缩放
	protected double oldScaleY;			//旧的Y轴缩放
	protected double oldOpacity;		//旧的透明度 
	protected int priority=0;			//优先级
	
	
	
	/* ---------------------- Action -------------------- */
	protected List<Action> actions = new ArrayList<Action>();
	public void runAction(Action action){
		if(action!=null){
			ActionManager.addAction(action, this, paused);
		}
	}
	public void stopAction(Action action){
		action.stop();
		actions.remove(action);
	}
	public void stopAllAction(){
		while(actions.size()>0){
			stopAction( actions.get(0) );
		}
	}
	/* ---------------------- 父子关系 -------------------- */
	protected Node parent=null;			//父节点
	protected List<Node> children = new ArrayList<Node>();		//子节点
	public void addChild(Node node){
		addChild(node, node.priority);
	}
	public void addChild(Node node,int priority){
		node.priority = priority;
		node.parent = this;
		synchronized (children){
			this.children.add(node);
			Collections.sort(this.children, new Comparator<Node>() {
				public int compare(Node o1, Node o2) {
					return o1.priority-o2.priority;
				}
			});
		}
		
	}
	public Node getParent() {
		return parent;
	}
	public void setParent(Node parent) {
		this.parent = parent;
	}
	public List<Node> getChildren() {
		return children;
	}
	/* ----------------------  -------------------- */
	public void setScale(float scale) {
		this.setScaleX(scale);
		this.setScaleY(scale);
	}
	public void setPositionX(float x){
		this.position.x = x;
	}
	public void setPositionY(float y){
		this.position.y = y;
	}
	public void setPosition(float x,float y){
		this.position.x = x;
		this.position.y = y;
	}
	/* ------------------------------------------------------ */
	public void draw(Graphics2D gl){
		
	}
	/* ------------------------------------------------------ */
	public Vec2 getPosition() {
		return position;
	}

	public void setPosition(Vec2 position) {
		this.position = position;
	}
	
	public float getRotation() {
		return rotation;
	}
	public void setRotation(float rotation) {
		this.rotation = rotation;
	}
	public Size getSize() {
		return size;
	}
	public void setSize(Size size) {
		this.size = size;
	}
	public float getScaleX() {
		return scaleX;
	}
	public void setScaleX(float scaleX) {
		this.scaleX = scaleX;
	}
	public float getScaleY() {
		return scaleY;
	}
	public void setScaleY(float scaleY) {
		this.scaleY = scaleY;
	}
	public float getOpacity() {
		return opacity;
	}
	public void setOpacity(float opacity) {
		this.opacity = opacity;
	}
	public int getPriority() {
		return priority;
	}
	public void setPriority(int priority) {
		this.priority = priority;
	}
	public float getAnchorX() {
		return anchorX;
	}
	public void setAnchorX(float anchorX) {
		this.anchorX = anchorX;
	}
	public float getAnchorY() {
		return anchorY;
	}
	public void setAnchorY(float anchorY) {
		this.anchorY = anchorY;
	}
	/* --------------------------- */
	/**
    recursive method that visit its children and draw them
  */
	public void visit(Graphics2D gl) {
	    // quick return if not visible
		if (!visible){
			return;
		}
		synchronized (children) {
			if (children != null) {
				for (int i = 0; i < children.size(); ++i) {
					Node child = children.get(i);
					if (child.priority < 0) {
						child.visit(gl);
					} else
						break;
				}
			}

			draw(gl);

			if (children != null) {
				for (int i = 0; i < children.size(); ++i) {
					Node child = children.get(i);
					if (child.priority >= 0) {
						child.visit(gl);
					}
				}
			}
		}
		

	}
	/*----------- Position ------------*/
	/**
	 * 获得节点对于场景的世界坐标
	 * @return
	 */
	public Vec2 getWorldPosition(){
		Vec2 vec = new Vec2();
		Node n = this;
		while(!(n instanceof Scene)){
			vec.x+=n.position.x;
			vec.y+=n.position.y;
			n=n.parent;
			if(n==null){
				return new Vec2();
			}
		}
		return vec;
	}
	public Vec2 getWindowPosition(){
		Vec2 wp = getWorldPosition();
		Scene scene = null;
		for(Node n = this;n!=null;n=n.parent){
			if(n instanceof Scene){
				scene = (Scene) n;
			}
		}
		return (scene==null)? new Vec2():new Vec2(wp.x+scene.position.x, wp.y+scene.position.y);
	}
}
